home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
vol_200
/
280_01
/
find1.c
< prev
next >
Wrap
Text File
|
1989-01-11
|
6KB
|
307 lines
/* [FIND1.C of JUGPDS Vol.46] */
/*
*****************************************************************
* *
* Written by Hakuo Katayose (JUG-CP/M No.179) *
* 49-114 Kawauchi-Sanjuunin-machi *
* Sendai, Miyagi 980 *
* Phone: 0222-61-3219 *
* *
* Modifird by Toshiya Oota (JUG-CPM No.10) *
* Sakae ko-po 205 *
* 5-19-6 Hosoda *
* Katusikaku Tokyo 124 *
* *
* for MS-DOS Lattice C V3.1J & 80186/V20/V30 *
* *
* Compiler Option: -ccu -k0(1) -ms -n -v -w *
* *
* Edited & tested by Y. Monma (JUG-CP/M Disk Editor) *
* & T. Ota (JUG-CP/M Sub Disk Editor) *
* *
*****************************************************************
*/
/* find1 - find patterns in text */
#include "stdio.h"
#include "dos.h"
#include "tools.h"
#include "toolfunc.h"
#define DEBUG 1
#define YES 0
#define NO -1
#define NOT_CHAR '!'
#define NOT 0x00800
#define NMASK 0x0FEFF
#define BOL_CHAR '%'
#define BOL 0x00125
#define ANY_CHAR '?'
#define ANY 0x0013F
#define EOL_CHAR '$'
#define EOL 0x00124
#define PCLOSURE_CHAR '+'
#define CLOSURE_CHAR '*'
#define CLOSURE 0x04000
#define CMASK 0x0BFFF
#define CCL_CHAR '['
#define CCL 0x02000
#define NCL 0x01000
#define ECL_CHAR ']'
#define GROUP '-'
#define UC '\\'
int np;
int spat[16][64];
void makpat0(),getccl0();
char esc0();
void main(argc, argv)
int argc;
char *argv[];
{
char line[MAXLINE];
int pat[MAXPAT];
#ifdef DEBUG
int i, j;
#endif
np = 0;
if (argc < 2) {
fprintf(stderr, "FND992 Usage: find1 pattern <infile >outfile\n");
exit();
}
makpat0(pat, argv[1]);
#ifdef DEBUG
printf("PAT[ ]");
for (j = 0; pat[j] != '\0'; j++)
printf("\nFND802 pat[%3d]=%04x", j, pat[j]);
putchar('\n');
for (i = 0; i < np; i++) {
printf("\nFND804 PAT[%1d]", i);
for (j = 0; spat[i][j] != '\0'; j++)
printf("\nFND806 spat[%3d][%3d] = %04x", i, j, spat[i][j]);
putchar('\n');
}
#endif
while (getline(line, MAXLINE) > 0)
if (match(line, pat) >= 0)
printf("%s", line);
}
/* makpat0 -make pattern from arg(from), terminates atdelim */
void makpat0(s, t)
int *s;
char *t;
{
register char *tt;
tt = t;
if (*t == BOL_CHAR) {
*s++ = BOL;
t++;
}
for (; *t != '\0'; t++) {
if (*t == ANY_CHAR)
*s++ = ANY;
else if (*t == EOL_CHAR && *(t+1) == '\0')
*s++ = EOL;
else if (*t == CLOSURE_CHAR && t > tt)
*(s-1) |= CLOSURE;
else if (*t == PCLOSURE_CHAR && t > tt)
*s++ = *(s-1) | CLOSURE;
else if (*t == CCL_CHAR && *(t+1) != '\0')
getccl0(np++,&s,&t);
else if (*t == NOT_CHAR && *t != '\0') {
t++;
*s++ = esc0(&t) | NOT;
}
else
*s++ = esc0(&t) ;
}
*s = '\0';
}
/* getccl0 - expand char class at arg(i) into pat(j) */
void getccl0(np,x,y)
register int **x;
register char **y;
{
char ss, st, ch;
int i;
#define s (*x)
#define t (*y)
t++;
if (*t == NOT_CHAR) {
*s++ = NCL + np;
t++;
}
else
*s++ = CCL + np;
for (i = 0; *t != ECL_CHAR && *t != '\0'; i++, t++) {
if (*t != GROUP)
spat[np][i] = esc0(y);
else {
t++;
ss = esc0(y);
st = spat[np][i-1];
if ((isdigit(st) && isdigit(ss) ||
islower(st) && islower(ss) ||
isupper(st) && isupper(ss)) &&
st < ss) {
i--;
for (ch = st; ch <= ss; ch++)
spat[np][i++] = ch;
i--;
}
else {
spat[np][i++] = GROUP;
spat[np][i] = ss;
}
}
}
spat[np][i] = '\0';
t--;
if (*t != '\0')
t++;
#undef t
#undef s
}
/* esc0 - map aray(i) into escaped character if appropriate */
char esc0(x)
register char **x;
{
#define t (*x)
if (*t == '@' && *(t+1) != '\0')
switch (*++t) {
case 'n' :
case 'N' : return ('\n');
case 's' :
case 'S' : return (' ');
case 't' :
case 'T' : return ('\t');
default : return (*t);
}
else if (*t == UC && *(t+1) != '\0')
return (char) toupper(*++t);
else
return (char) tolower(*t);
#undef s
}
getline(s,lim)
char *s;
{
register int c;
register char *p;
p = s;
while (--lim > 0 && (c = getchar()) != EOF && c != '\n')
*p++ = c;
if (c == '\n')
*p++ = '\n';
*p = '\0';
return (p-s);
}
/* match - find character anywhere on line */
match(text,pattarn)
int *pattarn;
char *text;
{
int i;
char *ss;
for (ss = text; *text != '\0'; text++) {
if ((i = amatch(text,pattarn,ss)) >= 0)
return i;
}
return -1;
}
/* amatch (non-recursive) - look for match starting at lin(from) */
amatch(text,pattarn,tp)
register char *text, *tp;
register int *pattarn;
{
char *temp, *tmp2;
int k, *newpat;
for (temp = text; *pattarn != '\0';pattarn++) {
if ((*pattarn & CLOSURE) == CLOSURE) {
for (tmp2 = temp; *tmp2 != '\0';) {
if (omatch(&tmp2,*pattarn & CMASK,tp) == NO)
break;
}
for (newpat = pattarn+1; tmp2 >= temp; tmp2--) {
if ((k = amatch(tmp2,newpat,tp)) >= 0)
break;
}
temp = tmp2 + k;
break;
}
else if (omatch(&temp,*pattarn,tp) == NO)
return -1;
}
return (temp-text);
}
/* omatch - try to match a single pattern at pat(j */
omatch(ln, pattarn, s)
register char **ln, *s;
register int pattarn;
{
int retv;
if (**ln == '\0')
retv = (NO);
else if (pattarn == ANY && **ln != '\n') {
(*ln)++;
retv = (YES);
}
else if (pattarn == BOL && *ln == s)
retv = (YES);
else if (pattarn == EOL && **ln == '\n')
retv = (YES);
else if ((pattarn & NOT) == NOT)
retv = (*(*ln)++ == (pattarn & NMASK) ? NO : YES);
else if ((pattarn & CCL) == CCL)
retv = iindex(spat[pattarn & 255],*(*ln)++);
else if ((pattarn & NCL) == NCL)
retv=(iindex(spat[pattarn & 255],*(*ln)++) == YES ? NO : YES);
else
retv = (*(*ln)++ == pattarn ? YES : NO);
return retv;
}
iindex(pat,c)
register int *pat;
register char c;
{
pat--;
while (*++pat)
if (*pat == c)
return YES;
return NO;
}